Node.js With Passport Authentication | Full Project

https://youtu.be/6FOq4cUdH8k

This video is sponsored by dev Mountain
if you're interested in learning web
development iOS or UX design dev
Mountain is a 12-week design and
development boot camp intended to get
you a full-time position in the industry
to learn more visit dev mountain comm or
click the link in the description below
hey what's going on guys so in this
video we're going to create a nodejs and
passport app and passport is used for
authentication of all types you have
local local strategy which is what we'll
be using where we deal with the the
database directly will be using MongoDB
you can use OAuth so Google github
Facebook Twitter you can use those to
log in you can use a JSON web token if
you're if you're using something like
react or view or some front-end
framework we're going to be doing
everything on the server we're going to
use ejs to display our templates we're
gonna be using Mongoose to deal with
MongoDB and there's some other packages
we'll be using as well so it's gonna be
kind of a long video I don't want to do
a series I don't really like doing the
series because usually the first video
gets a ton of views and then it just
kind of falls off so I don't really like
doing those but this is a redo of a
series I did about three years ago for
those of you that remember I had a node
in passport application that I built and
the code was just horrendous I just
updated it today and I think we all go
through that when we look at our old
code and it's just it's just
cringe-worthy but I yeah I updated it so
now updating the the series or rather
video in this case so this is it right
here this is the basically the welcome
page so we can choose to register or
login and you can use this kind of as a
boilerplate for for any application that
you want to implement server side
authentication with so let's say
register and we're using bootstrap we're
actually using boots watch which is a
themed bootstrap file and we're gonna
just log in here or register I think I
actually already have myself registered
so let's use a different name
a Sam Smith
let's do Sam at gmail.com and we're
using validation as well as you can see
so we're going to implement that and
register so now it says we're registered
and we can log in so let's try it Sam at
gmail.com okay once we log in it's going
to take us to the dashboard and it says
welcome Sam Smith and we can log out now
this dashboard is protected so you have
to be logged in to actually get to this
route so if I log out and I go to slash
dashboard you'll see that it doesn't let
me it just tells me I have to login to
view this resource so that's what we'll
be building guys hopefully you enjoy
this project we're gonna jump into
MongoDB comm because we need to create
our database now you can download Mongo
and install it locally if you want we're
going to be using Atlas which is is
basically Mongo in the cloud it's really
really easy to get set up I just did a
video on it about a month ago some of
you guys might may have seen that but
you just want to register so if you go
to get MongoDB fill this out and just
register and then hit login and I'll go
ahead and login
and the way that this works is you
create what's called a cluster and you
get one free cluster okay and I've
already created mine and called a test
cluster one so if you don't have one yet
just hit build new cluster choose AWS
for your provider your region will
probably be selected already and right
here you want to choose free forever
that the free plan it'll probably be
selected by default and then you can
rename your cluster if you want and then
just hit create cluster okay and then
that will create it now it does take a
couple minutes to create so you might
have to wait a few minutes you should be
able to hit the security tab though even
if it's still getting set up you do need
to add a user okay because the way that
you connect is through a URI string and
you need to have your username and
password so if you go add new user put
your username your password and read and
write to any database and then add user
okay once you do that you want to go to
IP whitelist
and AD IP address and you can add your
own IP address just by clicking this
button or you could do just all zeros
like that and that should just be you
know and anyone that has your password
and your username should be able to
connect and that's what I have here
alright so that should be all you need
to do create the cluster create the user
and add your IP address all right and
then once your cluster set up if you
click connect you can get your connect
string by clicking right here connect to
your application and then well either
one of these the first one is going to
be shorter but yeah here's the
connection string and that's all like
that you're gonna need and we'll
implement this later on alright so now
we're going to jump into vs code and I
just have an empty folder called node
passport login we're gonna run an NPM in
it
- why ok so it's going to create our
package JSON file it's gonna look like
this I'm gonna explain everything but
I'm gonna go kind of fast because I
don't want this to be too long of a
video and I expect that a lot of you
guys know the basics of node I do have a
node.js for beginners crash course on
YouTube I have an express crash course I
have a node.js udemy course
so there's plenty of resources as well
as other other content creators so let's
let's install our dependency so we're
gonna say npm install or I and we want
Express which is our framework we want
let's see we want bcrypt because we want
to encrypt our passwords
I'm sorry bcrypt j/s because you never
want to store plaintext passwords we
need passport for authentication and
then any strategy that you use with
passport you need to install as a
separate package so we want passport -
local because we're using a local
strategy we're also gonna need ejs which
is our template engine that we're using
and ejs by default doesn't have layouts
so we're going to install Express - ejs
- layouts ok we're also gonna need
Mongoose to deal with MongoDB and we're
gonna use connect - flash for flash
messaging and connect flash depends on
Express - session as well and I think
let me just make sure I think that's
everything that we need yeah it should
be everything so let's run that and that
those are all going to get installed
they're gonna get added to our package
Jason okay now there's one dev
dependency that I want to install and
that's node Mon so we're gonna say NPM
install - upper case D for dev
dependency and then node Mon and that's
just gonna make it so that we don't have
to keep restarting our server every time
we make a change
it'll just constantly watch it as we
save our files okay so now I just want
to add a couple scripts we want to start
script so if we deploy this thing it'll
just run node a pas it's what I'm going
to call our file in fact we can change
the this right here from index to app
and then let's put a comma here and
let's copy this down and we want a
script to run our node Mon app je s and
I'm going to call this dev that way we
can just do NPM run dev and it will run
node Mon so let's save this and close it
up and we're going to create our app dot
J s file and let's go ahead and bring in
Express and let's just do a basic
Express server first so we'll create
we'll initialize our app variable with
Express and let's go ahead and create a
port to run our app on we're gonna use
process dot e NV dot port okay in case
we deploy or 5,000 on our localhost and
then we're going to take our app object
and call listen which will run a server
we need to pass in the port and then we
can do console dot log and I'm gonna put
in some back ticks here so I can use a
template string with a variable I'm
gonna say server started on port and
then put in our syntax to put in a
variable all right so this should run
let's go ahead and try it so I'm going
to clear this up and do NPM run dev and
server started on port 5,000 now we
don't have a router anything so if we if
we do go to localhost port 5000 it's
just gonna say cannot get slash because
we don't have a route for that so we're
gonna have separate files for our routes
so I'm going to create a folder called
routes and we're gonna have two files in
here index dot JSON we might as well
create our users jeaious as well so
anything that's like slash for instance
the home page which is just / or /
dashboard those are gonna go in the
index J s and then user slash login user
slash registers those those routes will
go in here
so our index J ass
we're gonna be using the Express router
so let's say Const Express we need to
bring that in and then to use the
Express router we need to create a
variable called router and set that to
Express dot router and then let's do
module dot exports equals router and
then whenever we want to create a row we
simply say router dot and then whatever
the method in this case it's a get
request so we're gonna handle just the
the homepage or the index page and for
now let's just put an arrow function
with a request and response object and I
just want to take the response and call
dot send and we'll just send the text
welcome to the browser just to make sure
that this works now it's not going to
work just yet because in our app j/s we
have to add down here say routes and
we're gonna say app dot use let's say
app thought use slash and I want that to
pertain to say require I want that to
pertain to that index file that's in the
routes folder so dot slash routes slash
index okay so now if we go back here and
we reload we should see the text welcome
okay so let's see we might as well just
copy what we have in the index J s
go to users paste that in and let's do
slash login and we'll just send the text
login so say log in page and then let's
just grab this let's copy this down and
this will be the register so this will
be slash
register okay just to get the routes
down for the just displaying the pages
now in our app j/s we're gonna have to
do the same thing for slash users and we
want that to pertain to routes slash
users okay so now if I go to localhost
five-thousand slash users slash login we
get login and if I go to slash register
we get register alright so now that
we've done that let's let's start to set
up our views so that we can actually see
you can actually create our UI so we
need to bring ejs into a PJs we actually
don't need to bring it and we need to
initialize it we do however need to
bring in Express layouts so let's say
Express layouts and we want to set that
to require Express dot yeehaw - ejs -
layouts and then we need to add a bit of
middleware
so let's say ejs we need to do app dot
use Express layouts and then we need to
just do app dot set and we need to set
our view engine to ejs okay and make
sure your X this is above this or other
layouts won't work okay we'll save that
now we need to create a folder for our
views and inside views we're going to
have a file called layout dot ejs so
that's going to handle the layout around
all of our views and we might as well
just create all of our views will have
welcome which will be the home page and
you should all have ejs extensions we're
gonna have login dot ajs and register
dot ajs and then we're also going to
have a dashboard
okay and I think and we just make sure
that's it we are gonna have a partial
for the messages but we'll get to that
later so let's go to our layout ejs and
I'm gonna type this out but the other
views I'm probably just gonna paste in
just to save some time but the layout
let's go ahead and generate a
boilerplate with Emmet so we'll do
exclamation enter or tab and for the
title will say no dot J s and passport
app and like I said we're gonna be using
boots watch so let's head over to boots
watch.com and basically I mean you can
pick from any of these themes I'm using
this journal theme so if I click
download it gives us the CSS so I'm just
gonna grab the link here and use that so
let's let's go right here and say link
paste that in we're also using font
awesome so let's go to font awesome comm
and grab this and put that right here
okay now we are going to use the flash
messages I'm using dismissible alerts
the bootstrap dismissible alerts so we
do need the JavaScript so we'll go to
get bootstrap comm get started and then
we'll grab we are we don't need the CSS
we already have the boot so watch CSS
but we do need these three script tags
and we'll put that in the layout right
above excuse me right above the ending
body tag okay so let's put in the body
let's do a container class and then we
want to output any views that are
supposed to be displayed and the way
that we do that with what are we using
ejs is we use an angle bracket percent
and then a hyphen and then the word body
and then we do percent and then
bracket okay so that's gonna basically
output whatever view that should be
output on that page so let's save this
and now if we go to welcome ejs and just
put an h1 in and say welcome and save
this this is what we want to render for
the the index page now remember we go to
our routes index j s and we have the
route for that page so we're gonna do
res dot render and the view that we want
to render is welcome okay so now if I go
back to localhost 5,000 we should see an
h1 with welcome alright so what I'm
gonna do now is I'm gonna paste in the
the views now if you want you can go to
the repository
I'll have it of the link in the
description too to the repository let me
see it's right here so if we go to views
and let's see let's go to welcome ejs
and just grab this markup right here and
go to welcome ejs and i'm gonna paste
that in so basically it's just it's just
bootstrap markup we have a row where we
have margin top we're moving it down six
column div here m auto will push it to
the middle we're using a card so we have
a border and some padding h1 has the the
nodejs
icon and then we just have a register
and a login button so let's save that
and let's check it out so if we reload
it should look like that alright now
let's do the register right now it's
just showing the text register what we
want to do is render the register
template so we'll go to our route users
j/s let's change this to render and then
this will render login and then we want
this one to res dot render register
okay so let's let's grab from the
repository let's grab Hugh's register
ejs and I'm going to just copy this and
let's go to register ejs paste that in
and I'll just quickly go over this again
just using the the bootstrap grid where
we have an h1 with an icon register this
right here this include partials I'm
actually going to comment that out for
now and then we have our form the action
is going to go to users register and
it's gonna be a post request and then
we're just sending our name we're
sending a you know type ID name class
place holder now the value here we have
some ejs in here because what this is
saying is that if there's a name like if
we type something in and then the
validation doesn't pass we don't want
the form to completely clear we want to
keep whatever's in there so we're saying
if typeof name is not equal to undefined
then we want to display whatever that
name variable is okay and we're gonna
pass that into this view if we need to
else then it's just going to be blank so
we have this for all of the the values
here okay so that's what that is
and then at the bottom it just says have
an account if we do then we have a link
to to log in so we'll save that let's
make sure that renders so if we go to
register could not find the included
file messages partial messages I
commented it out I guess comments don't
work in ejs I didn't know that all right
we'll just delete it for now okay so we
have our register now let's grab the
login so I'll go back to the repository
views login ejs basically the same thing
except it goes to the login route we
paste that in login ejs we'll get rid of
the include for now
but basically the same thing it's just
getting submitted to users login so
let's save that and go back okay now we
should be able to click the log in here
good so now the register and login pages
both display we might as well do the
dashboard while we're at it
so let's view x' dashboard ejs which is
very simple and go to dashboard ejs and
paste that in ok and it's going to show
it this user dot name once you're logged
in once we set up passport and all that
we'll have access to the user object and
we'll have access to all the fields that
that we have in our database all right
so the ejs should be all set up so let's
close that up let's just close all of
these it's probably confusing you guys
having so many open alright so we have
our views now what I want to do is bring
in mongoose connect to our database and
so on so up at the top here in app j s
let's bring in mongoose
all right and then we want to connect to
our database so we're gonna go right
down here and actually you know what we
need to create our config file our
config folder so let's do that create a
folder called config and I'm going to
store the Mongo string the connection
string in a file called keys Jas okay
and keys Jas we're just gonna say module
dot exports and we just want to explore
it an object and let's do Mongo URI and
then we'll put our Mongo URI in here
let's see so I'm going to go back to
atlas go to connect what I showed you
before connect your application this one
right here and we're gonna grab this
okay so once we grab that we can paste
that right in now I just need to put
your password in right here mine's the
same as my username and we'll save that
and now we can bring this into our App
J's file so that we can connect to our
database so let's go right here let's
say DB config and let's require oh sorry
we want to set a variable of DB we'll
set that to require our keys file which
is in config slash keys and then we want
the Mongo URI like that alright so set
that and then we can connect to Mongo
and the way that we do that is by using
Mongoose and we want to use dot Connect
okay and we want to pass in our DB now
we're gonna get a warning spit out at us
unless we put in this object here and we
put in use right here use new what new
URL parser and we want to set that to
true if we don't do that we're gonna get
some some complaints in the in the
console so we want to do that and then
this will return a promise so we're
actually gonna go on the next line and
do a dot then and a dot catch okay if
there's dot catch if we have an error
then let's go ahead and just console dot
log it okay dot then we'll just we'll
just console log let's console log
MongoDB connected okay and now down here
you can see my save server started and
then we get MongoDB connected all right
so our database is connected now what I
want to do is create our model okay so
we need to create a user's model or user
model so we'll create a folder called
models and inside there we'll create a
file called user uppercase you user dot
J s and then we just need to basically
put in we need to create a schema with
all the different fields that that we
need for a user so we're gonna bring in
mongoose
all right and then we're gonna create
our schema so let's say Const user
schema and that's gonna equal new
Mongoose dot schema all right and then
here we're gonna pass in an object with
all our fields so we're gonna have a
name and we're gonna say that type is
gonna be a string okay and then we want
this to be required
so we'll say required true all right and
then let's just copy this down see we
need three more so let's change this one
the second one to email also going to be
a string also required next one is going
to be password okay and then this last
one is going to be date and then date is
gonna be type of date and let's get rid
of let's actually change required to
default because we want to have a
default value of whatever the date is
right now so we can do that with date
dot now all right and then let's see we
want to export this first we'll just put
this in a variable so Const use R equals
Mongoose dot model okay we want to
create a model from our schema so we
pass in the model name which is user and
then we want to pass in our user schema
and then we're just gonna export this so
that we can use it in other files okay
and that should do it so let's save this
and we can close that up
now first thing we're going to work on
is is the registration let's see
now since we're getting data from the
form we need to add in our body parser
middleware which now is part of Express
before we had to install body parser as
a separate module but now it's actually
included with Express so let's put that
right under the ejs middleware okay so
we can simply say app dot use Express
dot URL encoded just like before we
would do body parser you want URL
encoded now we can do this oops and we
just want to pass in extended false that
way we can get data from our form with
request dot body let's see what else we
doing here
yeah so let's go to our routes users dot
j s and remember when we submit our
registration form it's gonna make a post
request to slash user slash register so
let's say register handle will do router
dot post because we're handling a post
request to users slash register we don't
have to put in user because we're
already in that in that file and we
basically said you know connect users to
this file so let's say slash register
put an arrow function here request
response alright and just to test this
out let's do a console log and let's do
request dot body ok and then I'll just
do res dot send whatever hello ok I just
want to I just want to see if what we
pass in the form actually is gonna be in
this request stop body so let's go back
to our application and close this stuff
up and in our application let's go to
our register and let's put in some stuff
here
doesn't really matter what and login so
that's just gonna show hello but what we
want to look at is our console down here
and you can see that we have all of our
information from the form alright good
so now let's put each thing into a
variable and I'm going to use a little
bit of destructuring for that so if we
do Const and then some curly braces we
can pull stuff out of requests dot body
okay so we can pull out for instance
name email password and password - okay
so we're pulling those variables out now
we should do you know let's let's do our
validation before we actually submit
hold on yeah let's let's do our
validation so we're gonna actually just
initialize an array called errors and
let's first check for let's say check
check required fields
so we'll say if not name or not email
basically they're all required so we're
going to make sure that they're all
filled in
all right so if any of those if this is
true then we want to take errors and we
want to push onto it I'm just going to
push an object with a message and the
message will say please fill in all
fields okay so it's the first check I
want to do next let's do check passwords
match
so we'll say if password is not is not
equal to password - then let's do errors
dot push and we'll say message passwords
do not match all right so this is a
little next thing I want to check is to
make sure that the password is at least
six characters long so let's say check
past length and this there's a ton of
ways to do this guys if you if you want
to do something else if you want to use
some kind of you know third party
package or something that's fine as well
I'm just trying to keep it simple here
so let's say if password dot length is
greater than I'm sorry less than six
then we want two errors dot push an
object with a message then we'll say
password should be at least six
characters all right so that should be
good for validation once we once we
search for the user I'm sorry once we
begin to register the user we want to
search for to see if it's already there
to see if that email already exists and
then we'll do another error but this
should be good for now so I guess what
we'll do is
we'll say if arrows dot length is
greater than zero that means that we
have an issue else let's just do res dot
send and we'll just say pass okay now if
there is an issue okay so if the if any
of these are true then I want to
re-render the registration form so let's
do res don't render and we want to
render register okay and then we want to
pass some stuff in when we will use ejs
or any template engine when we render it
we can pass in values okay basically
variables we want to pass in the errors
okay because we want to basically loop
through and display those messages we
also want to pass the data in because
again if we look at the registration
form in our value or checking to see if
name is here email or whatever because
we don't want the form to completely
clear when we you know when we submit
the form and it's in it's not valid so
let's pass in name email password and
password - okay so let's save that now I
mean we can try it out so if we go to
register it's just refresh this so if we
login if we click login we get nothing
if we put a name in you can see it does
stay there that's what that value does
let's put an email and let's put a
password so this still doesn't work the
password needs to be six characters they
also need to match so let's just do one
through six let's make a match and login
and we pass now obviously I mean we need
to let the user know what the hell is
going on when we when it doesn't work so
we need to have some errors here some
messages all right so what we'll do is
create a partial so in our views we're
going to create a folder called
partials and all a partial is is just a
piece of markup you know some HTML or
whatever that we want to put inside of
another template file so we're gonna
call this let's say new file will call
this messages dot ejs okay and then
inside messages we're gonna check to see
if errors exists okay because right here
when we render the register we're
passing in errors and when we render it
normally in our get request right here
we're not so we need to check to see if
those errors are there so let's do that
in messages now ejs syntax again is
angle brackets and % so we're gonna say
if and in the way this works it's very
very similar to reiax JSX
well it's not specific to react but it
that's what it's best known for JSX is
is JavaScript inside the HTML and that's
basically what ejs is only instead of
using you know curly braces we use these
angle brackets and percent which is a
bit ugly but it basically does the same
thing we can do an if statement we
started out oops we start it out and
then we end it down here okay but we
have to have these tags in order to you
know for that to be JavaScript so the
way that we test to see if the errors
are there is by checking the type and
making sure that it's if it's equal to
undefined that means that they're not
there so we're gonna say if typeof which
is just a JavaScript expression will say
if typeof errors is not equal to
undefined then that means that there is
an error now if there was an error we
want to display that right we actually
want to loop through them because errors
is an array so in ejs we can use a for
each so we can do I mean it's JavaScript
so
of course we can use it so we'll say
arrows dot for each now let's see we're
gonna want to it's it's kind of hard to
write when you have to like separate it
like this but we're gonna put a function
in here okay and we have to make sure
that we this has tags around it like
this and up here okay so for each error
let's call it error all right and then
inside here is where we want to put the
message now remember it's an object with
a property of MSG or message so let's
put that in here now if you want to
actually output with ejs you want to put
an equal sign so we'll say error dot msg
and then we'll close it all right so
let's save that and let's see if this
works
so if i try to submit this oh you know
what we didn't insert it we didn't
insert the partial into register so
let's go back to register ejs and we'll
go ahead and put this in here now to put
in a partial and we need to just say
include let me just double check the
syntax here yeah so we just want to
include partials slash and then messages
like that should work so let's try let's
save it and of course we could have just
put this right inside register but I'm
going to be using this in login as well
so a partial is is this is a good you
know good time to use a partial so it's
in there we go now this looks like crap
I mean we obviously want these on
separate lines I want to wrap them in
the bootstrap alert markup so what I'm
gonna do is go to get bootstrap calm
because I can't remember the the mark-up
for the dismissible alert so we're gonna
go to components alerts and we want
dismissing okay right here because we
want to be able to exit out so what I'll
do is just simply grab this and inside
of our messages here I'm going to
replace this will put it back what we
want to put in our markup and we just
want to replace this line with what was
just here so error dot msg all right and
I guess I'll keep the alert warning
that's gonna be like a yellow color so
let's save that and now it should look a
hell of a lot better so login oh this
should actually say register not login
let's change that or is it right here so
register and there we go so passwords
don't match and we can close them up
good so we have the validation down now
now it's time to actually add it to the
database and notice we haven't we're not
using passport yet passport is for
authenticating all we're doing now is is
basically uh you know creating a
resource so we're creating a user and we
also have to encrypt the password that's
another thing we have to do so let's go
back to our users route and now we want
to work in here because we want to deal
with you know if the validation passes
so we can put a comment here say
validation pass so now what do we want
to do we want to use our model right
because the way that Mongoose works is
is you create a model such as user and
then you have methods that you can call
in that model
like save find things like that so we're
going to bring in our model up top here
so we'll say Const user equals require
and we're gonna go outside of the routes
folder into models and then we want user
okay so we should now be able to call
methods on user now I want before we
submit the user we want to make sure
that it doesn't exist so first thing
we'll do is take our user model and
we'll call find one which is a mongoose
method that does just that it finds one
record and our query is going to go in
here so we're gonna say we're email
equals email okay remember we have that
as a variable that's being what that's
what's passed into the form and we want
to match it to a user in the database
now this is going to return a promise so
we're gonna do say dot then and let's
see you know say dot then and that's
going to give us the user and what we
want to do is check for that user okay
so if there is a user then what I want
to do is basically the same thing we did
here we want to re-render the register
form and we want to send along an error
okay so I'm gonna just copy this and
I'll put a comment here we'll just say
user exists' we'll paste that in and
yeah that should do it
except we just want to add a new error
so right here we'll say errors dot push
and we want to push on msg user or let's
say email is already registered
and that will pass it in here okay and
then this is gonna have an else and
let's do well I guess we'll just keep
going we'll test it after now if there
isn't a user then of course we need to
create a new one but we have to encrypt
the password so we're also going to
bring in bcrypt so up here let's say
Const bcrypt
and we're gonna require bcrypt dot not
dot j us just be crypt j s okay and then
let's go down and inside the else we're
gonna say Const new user and we're gonna
set this to new user okay when when you
have a model and you want to create a
new instance or in this case a new user
we want to use the new keyword and then
we want to pass in the values so we want
to pass in name email and password okay
now this is just es6 for this so this is
the same thing same thing up here you
know we're just shortening it so just in
case you don't understand that syntax
it's just an object
now this password is gonna be plain text
right in fact I guess what I'll do is
I'll just console.log a new user and
let's just res dot send hello I just do
the res dot send so it doesn't hang
what's this true is not defined required
true way what oh this is in our model Oh
required true this should actually be
lowercase this isn't Python
t.t alright alright sorry about that so
let's head back over to users je s let's
actually try it out and if we submit an
email that isn't registered we should at
least see the console log of the new
user so let's do that let's try one that
does exist I believe Brad at gmail
exists I can actually check real quick
in my cluster hopes collections let's
see no it doesn't exist Kevin Smith does
our Kevin at gmail so let's first try
one that does exist we know Kevin at
gmail exists so we'll go ahead and use
that with the pass validation as well
okay so emails already registered
perfect so now if we use Brad at Gmail
which doesn't exist we get hello and if
we look in the console you can see the
new user now MongoDB adds wait a minute
okay
MongoDB adds an underscore ID this is an
object ID it adds it automatically now
this is not in our database yet okay we
did new user but we didn't call user
save this this will create basically
create the instance but we haven't saved
it yet and I can show you that if I go
back into Alice and I reload you can see
that Brad at gmail is not here alright
so we know that this is working but the
password is plaintext so we certainly
don't want that so let's get rid of
these two lines and let's do it say hash
password
so we have to use bcrypt for this and
what we need to do is is generate a salt
okay we need to generate a salt so that
we can create a hash so bcrypt has a
method called gen salt okay and this
takes in basically the I forget what
this is it's like the number of
characters or if you want to look at the
the bcrypt documentation you can do that
but we want to pass in ten here and then
we have a callback in this case an arrow
function and this is going to give us an
error if there is one and then salt okay
so it's going to give us our salt and
then we want to do bcrypt dot hash and
this hash is going to take in our
plaintext password and the salt and it
will give us a hash back
okay so let's pass in our plaintext
password so new user which is the object
we created right here the password so we
can get that with dot password and then
it also takes in the salt that we just
generated with gen salt and then it's
gonna give us a call back so let's use
arrow function here actually see here so
this will give us let's so let's open up
some curly braces here so this will give
us an error possible error and the hash
itself so basically the hashed password
let's put this on a new line
yeah we'll go like that I don't have
prettier I usually have the prettier
extension enabled in vs code which will
kind of format everything automatically
and I think that that's made me lazy
with with as far as formatting my code
alright so we'll get the hash right here
let's check for the error actually we'll
just do if error throw error okay and
then we want to set the new user dot
password we want to set that now to the
hash okay so now it's gonna it's not
going to be plain text anymore it's
gonna be the hashed password and then we
just need to save the user
okay so we'll put a comment here we'll
say set password to hashed and then
let's go ahead and save the user by
saying new user dot save now this will
give us a promise so let's do dot then
and dot catch okay if it gives us an
error then we'll just console.log it and
if it passes if the user gets saved then
we want to redirect we want to redirect
to the login page because right now
we're registering a user so in this dot
then it will give us the user back and
let's do res dot redirect and will
redirect to slash login
all right so let's try this out so I'm
gonna go to my register page and let's
try to register myself and the password
should get hashed so we'll go ahead and
check this out let's register so it
redirected me to all its supposed to be
users login but that's that's not
important let's see if it actually got
saved so we'll reload and right here
Brad Travis see Brad a gmail and if you
look at the password it's completely
hashed we also have our object ID so
everything works we just need to change
the redirect to go to users slash login
now I would like it to say you know
you're now registered you can login
instead of just going to the login page
so since we want let me just get rid of
this since we want the message to be
shown after a redirect we need to use
what's called a flash message which
basically stores it in a session it
stores the message in a session and then
displays it after the redirect what we
do here when we show messages
we're actually rendering a view and
we're just passing this these messages
in when you redirect it's a different
story so we have to implement connect
flash okay so that has its own middle
layer so we have to go to app J s and it
also needs express session which we also
installed so let's see we're gonna bring
it up here
this is apt j s we're going to bring in
flash we're going to set that to require
connect that
Shh and then let's also say Const
session and I'll set that to require
Express - session all right now the
middleware for this let's put this go
right under the body parser and let's
put the Express session middleware and
we can actually get this from the
documentation just search for Express
session and we want was the github page
just go to it from here okay so this is
the Express session github and we want
this yes we want this right here if you
want to copy it from the repository you
can do that as well so app dot use
session secret doesn't matter what this
is just say secret resave we actually
want to set that to true and then save
on initialize we'll keep it true we
don't need this cookie right here I'm
not exactly sure what resave and save
uninitialized is I just know that this
is the correct middleware alright now we
also need to add a line of middleware
for connect flash which is just app dot
use and we want to pass in the flash ok
so now that we've done that so now we
should have access to request dot flash
but what I'm gonna do is since we're
gonna have different different colors
for different messages like like we want
the yellow for errors we want green for
success I'm actually going to create
some global variables for that so let's
say global bars and the way that we can
do this is just by adding our own
middleware will say app dot use and then
we can just put a function in here next
let's do an arrow so we can just put a
function that takes in request/response
next okay so anytime you want to add
middleware we can just do this and we
can set global variables by doing rep
res dot locals dot and then whatever we
want the variable in this case I'm going
to use success underscore MSG and I want
to set that to request dot flash because
since we implemented connect flash we
have this this flash object and then I
want to pass in just success underscore
msg like that alright and I'm going to
do the same thing for error message
except it's gonna be locals error
message alright so and then we just need
to call next okay so we just have a
piece of custom middleware that has some
global variables in it and we should be
able to call this success message an
error message and it's it's gonna come
from flash now back in our users j/s
when we redirect we want to call that
flash message right before that so what
we can do is simply pass in request dot
flash and we want to pass in here
success underscore message and then
we'll put our text and we'll just say
you are now registered let's say you are
now registered and can log-in ok so I
mean this takes care of creating the
flash message but we have to display it
so to do that I'm actually going to go
into our messages ejs and we're gonna do
the same type of thing we did for the
errors that were passed in now the way
that the the success message is gonna
work this this global variable we
created if it's not there it's just
going to be an empty string so that's
what we're gonna check for so let's go
under this and let's do let's do an if
so we're gonna say if and then we should
be able to just check for success
underscore msg and we should say if that
is not equal to an empty string then we
want to show the message okay but we
need to put our EJ EJ s tags in here
all right so if there's a success
message then we want the same kind of
dismissible alert so I'm going to copy
this whole div paste that in but I'm
gonna change it to alert success so that
it's green and then instead of error dot
message we simply want to put in our
success underscore message variable okay
and then we want to do the same for
error message so I'll copy this whole
thing and we'll change this to error
underscore msg will change the success
back to warning and change this to error
message okay so this should now work
because we in our actually it shouldn't
work just yet because our login doesn't
have the the include of the the partial
right here so I'm just gonna grab this
and put this in login ejs right below
the h1 okay so now we'll go and try this
out I'm actually going to go to my atlas
and delete some of these some of these
guys and delete all
all right so let's go back and refresh
our register and we'll just go ahead and
register a user and there we go you are
now registered and can login okay so we
had to use the flash message because
again we're redirecting so we're storing
it in the session so our registration is
complete now we're going to move on to
the login and this is where passport
comes in so let's try to think of the
best way to teach this let's close up
everything just to kind of start from
scratch here now remember I said we're
using a local strategy now we have to
put this inside of a config file and
we're gonna call this Passport
I mean you don't have to put it in a
config file but that's it I think it's
the best way to do it so inside here we
want to create our strategy so we're
gonna say Const and we're gonna call
this local strategy and this stuff is
all in the documentation of Passport if
you want to check that out it's not very
organized but it is in there so here we
want to require let's say require
passports - local and then we want to
say dot strategy ok so we're bringing in
the local strategy and then we're also
going to bring in Mongoose because we're
logging in which means we need to check
to see if the email matches the password
matches so we're going to be using
Mongoose for that so we'll require
Mongoose alright and then we also want
to bring in bcrypt because we need to
decrypt the hash to make sure that the
passwords match so let's say bcrypt
are not bcrypt but compare the hash to
the plaintext it's to require bcrypt j/s
okay and then we're gonna bring in our
user model so let's do let's see dot dot
slash outside of the config then into
models and then we want user alright now
we want to export the strategy that
we're going to create so module dot
exports and this is actually going to be
a function and this is going to take in
passport we're gonna notice I didn't
include passport up here we're gonna
pass it in from the app.js file so we
want to take that passport
object and just say passport dot use and
then we want want to say inside here new
local strategy and we want to add and
some options such as user name field now
you could have user name if you want
we're not using as user name so we want
to say email is going to be our user
name this should actually be a string
alright so use your name field as email
and then after the curly brace here
we're gonna put in our arrow function
and this is gonna take in three things
it's gonna take in email password and
done so basically the first thing we
need to do is is match the user we want
to first check to see if if there's an
email in the database that whatever it
whatever they pass in is there an email
with that or I'm sorry is there a user
with that email so let's say match user
alright so the way that we can do this
is by using Mongoose well do find one
just like we did with the validation and
we'll say see if there's an email that
matches this email and then if there is
we're gonna get a promise so we'll do
dot then let's also do dot catch alright
so for dart catch alright in the dot
then let's see yeah inside the dot then
it's going to give us the user it's
either going to give us the user or it's
gonna give us no I believe so we want to
say user then we'll use an arrow
function we'll say if not user okay so
basically if there's no match then what
do we want to do we want to return done
okay done is this this callback here we
always want to return done but we want
to pass in null for the user right I
believe no null is the error we don't
want to send an error but we do want to
say as you can see right here it's it's
error the user and then options
so we'll say null for the error false
for the user and then for the options
we're gonna put in our message okay and
our message is gonna be that email is
not registered okay so that's what we
want to happen if the user is not there
if it is there then we're gonna keep
going now we haven't dealt with the
password yet we've only matched the user
email so obviously the next thing we
want to do is match the password now to
do that we need to use bcrypt because
the password and the database is hashed
the password they submit is not so we're
gonna take bcrypt and we're gonna call a
method called compare and this actually
takes in the password which is going to
be passed right here okay
so we want to take that password and
then we want to take the user dot
password which is the hashed password
because remember this user is coming
from the database right we're finding
the email if it matches it skips this
and we now have the the hashed password
and we're also passing in the plaintext
password so we want to basically compare
these and then we have a callback okay
and then this callback is going to have
an a possible error and then is match
this will be a boolean okay so if it
matches that'll be true let's just check
for the error and we'll say throw error
and then we'll check for his match to
see if that's true
okay so if is match is true that means
that the user that it's passed right so
what we want to return our done function
and we want to pass in null for the
error and then user for the user okay up
here we return done but we return false
for the user this time we're actually
passing in the user else if it doesn't
match then we want to return done we
want to pass in null and we want to pass
in false because it doesn't match and
then a message just like we did above
okay and for our message I'm just gonna
say password incorrect alright now that
is our local strategy now this there's a
couple other things we need to do here
after our exports
I'm sorry not after our exports but
after our strategy we need to serial it
we need a method for serializing the
user and deserializing the user all we
have to call those methods and if we go
to the passport documentation let's see
and like I said this this documentation
gives you everything you need but it's
it's like out of order it's not it's not
very easy to understand but what I'm
looking for is the serialized and DC
let's see so this is kind of what we
were just doing no it's not that's what
we still need to do what we did let's
look over here yeah I hate this
documentation authenticate we're gonna
do that configure right here is what we
just did
so passport use local strategy username
password done look for the user we
returned done blah blah blah this is
this is exactly what we just did the
hell is it right here so this passport
serialize user deserialize user in a
typical web application that credentials
used to authenticate a user will only be
transmitted during the login request if
authentication succeeds a session willis
to be established and maintained via a
cookie set in the user's browser each
subsequent request will not contain
credentials but rather the unique cookie
that identifies the session in order to
support login sessions passport will
serialize and deserialize user instances
to and from the session so that's what
this does okay and we're gonna grab both
of these copy it and we're gonna go and
put this right in here alright yeah just
like that and then we should be all set
with this file let me just double check
this make sure this is right so dun dun
err oh yeah and if we want to keep this
consistent we'll just we'll do arrow
functions here
all right so that should work now what
we need to do is add a couple lines of
middleware if we go back here we need
these two lines right here passport
initialize and passport session so copy
that and we're actually gonna put that
inside of our app dot J s okay and it's
it's important where we put this we want
to put it after the Express session
middleware okay we'll put it right
between that in the flash I'll say
passport middleware okay that's that now
passport is not defined so basically no
this is this is initializing our local
strategy right and it's telling us
passport is not defined because we
actually need to we need to require this
file in our app J s and we need to pass
in passport so let's go up top and we'll
go yeah we'll go right up to the top
here and let's say passport config we're
just gonna simply require dot slash
config slash passport and then we're
going to pass in passport which we
actually have to bring up here so Const
all right so if we save that that error
goes away good and this this file is now
being required all right now we haven't
created our route yet right when we
submit this login form when we submit
this it goes to users slash login it
makes a post request to that route so we
have to handle that we have to basically
tell that route to use the local
strategy so let's head back over to
routes users Jas we're gonna go down to
the very bottom here and let's say login
handle and we're gonna take router dot
post because we're here we're handling a
post request to users slash login all
right now let's see we're gonna have to
bring in passport to this file as well
so it's a Const passport
and I can actually actually did show you
in the documentation where it said
passport authenticate that's all we need
to do so if we go up here see app get
log in there's the function and then the
crawling passport authenticate calling
the local strategy and then a function
and there's there's also some options
that we can put in as well so basically
we have to do this and we have it's
important to remember to do this at the
end we have to put a set of parentheses
with request/response and next all right
so let's go ahead and do that okay so
let's say passport dot authenticate
we're using the local strategy pass in
local and we're gonna pass in some
parameters here I want to do a success
redirect so on success what do we want
to do we want to get redirect to slash
dashboard alright a failure redirect we
want to go back to the login page so
slash users slash login and then I also
want to show a flash message
so we'll say failure flash and we'll set
that to true
okay and then we need to put like I
showed you those parentheses and then
request/response
next okay and that should implement our
strategy so we'll save that now let's go
back to our application and let's try to
log in with a with something that's not
going to work so I'll say like tech guy
info next is not defined oh we have to
put next right here let's try that again
okay so it just reloads the the login
page right now in order to show that
flash message what it does is it gives
us requests
I think it's requests dot error no it's
actually in request dot flash error so
I'm actually going to put that as a
global variable like we did with the
other messages so right here in global
variables let's actually we'll copy this
down and this is gonna be just for error
because that's what it's going to be put
in when we say show the flash for for
Passport
okay and then we're gonna go back into
messages because we need to check for it
and display it if it's there so it's
it's basically gonna be same as this so
we'll copy this except it's just error
not error message so we'll get rid of
that and then we'll go ahead and just
show error
so we'll save that now if we try to log
in let's reload this we try to log in
with something that email is not
registered okay if we do let's see what
is registered okay so we have Brad at
gmail is an actual user so let's do Brad
gmail but let's do the wrong password
and we get password incorrect all right
so let's do Brad at gmail and let's do
the correct password and login and we
get redirected to the dashboard now we
haven't created that route yet but the
login system is is working the
registration is working the login is
working all we have to do now is create
the dashboard and the log oh so let's do
that let's go to our index route and
let's see we'll put a comment here this
is the Welcome page and let's see we'll
copy that down so we'll say / - board
and we want to render the dashboard view
which we'll save and then let's see our
dashboard ejs this username this is
going to give us an error right now
because we're not passing that in yet so
I'm just gonna say welcome user and then
I'll put that back after but now if we
go to dashboard and reload we can see it
now let's give functionality to this
logout okay so I'm just going to make it
so that if we make a get request to
slash logout then it logs us out
so in our routes users j/s let's go down
here and let's say log out handle
and let's say router get the log out
all right now logging out is actually
very easy all you have to do is call
request dot log out using the passport
middleware it gives us the logout
function we can just do that but I do
want to send a flash message and
redirect so I'm gonna say request dot
flash whenever you want to send a flash
message we can just do that request dot
flash and we're gonna use success
underscore message score message and
then the text will just say you are
logged out and then we'll redirect so
res dot redirect and we want to redirect
to the login okay and that should do it
for a logout so let's save let's go back
and click logout you are logged out now
as it is I can go to dashboard even
though I'm not logged in which we need
to fix so what we need to do is
implement ensure authenticated so let's
go and let's create inside config a file
called auth dot J s okay so this is like
an auth guard so let's say module dot
exports equals an object called and then
we're going to have a property here
called ensure authenticated our function
called insure authenticated it's a
function
and then this is gonna take in
request/response next and we have method
attached to the request object called is
authenticated so that's what we want to
check for
okay so passport is giving us all this
stuff like this is authenticated so
let's do that and then if we're
authenticated we just want to simply
return next else or we don't even need
an else we'll just put here request dot
flash and let's do an error message
error message and let's say please login
to view this resource and then we just
want to redirect slash login okay so now
we should be able to bring this this
file in and we should be able to add
this as middleware to any route so any
route that we want to be protected we
just need to add this to so let's go
back to index j s and we want to want
this dashboard to be protected so what
we have to do is bring in say Const and
sure authenticated and we want to bring
that in from require and we're gonna go
dot dot slash config slash off okay and
then all we have to do is Pat is pass it
in as a second parameter like that and
now it's protected so we'll save let's
reload and we can't view it okay now I
want the user name to be able to show so
what I'm gonna do is when I render the
dashboard let's just put this on a new
line when I render the dashboard I'm
going to pass in an object and I want
user to be set to the
user because when we're logged in we
have access to request dot user and then
any field like name email and so on so
we're gonna pass that and actually I
think a better thing would be just to do
quests dot user dot name and set this to
name that way we don't pass the entire
user in just the name and then back in
our dashboard ejs let's go ahead and
replace this with our ejs syntax to put
in a variable and we'll just say name
all right let's try that out
so we'll log in we can see our dashboard
and we get welcome Brad Travis E awesome
we can log out all right so that's gonna
be it guys I know this was a friggin
long video I only expected it to be
about an hour or so but I guess I guess
it was quite a bit of code and don't
worry if you don't understand every
single line everything we did and feel
free to use it as a boilerplate for
future applications if you want to build
a blog or something you now have
authentication in place if you want to
add extra fields that should be easy
just update the model and you know your
the stuff in your routes and so on but
that's gonna be it guys I really hope
you enjoyed this if you did please leave
it a like and I'll see you in the next
video so I just want to give a quick
shout out to two of my top patrons
Carlos who has his own great YouTube
channel for developers and Igor from
park flyer Explorer comm who offers SEO
solutions for those of you that are
looking to rank your website high in
Google and generate more visitors so
I'll have both links in the description
below.
